package org.jin.samples.web;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

import javax.security.auth.Subject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.jin.samples.model.ExamScore;
import org.jin.samples.model.ExamSubject;
import org.jin.samples.model.ExamTest;
import org.jin.samples.model.ExamTestType;
import org.jin.samples.model.TestList;
import org.jin.samples.model.TestQuestion;
import org.jin.samples.model.vo.CommonMessageResultVO;
import org.jin.samples.model.vo.ExamScoreVO;
import org.jin.samples.model.vo.ExamSubjectVO;
import org.jin.samples.model.vo.ExamTestVO;
import org.jin.samples.model.vo.ExamUserVO;
import org.jin.samples.page.PagerModel;
import org.jin.samples.service.IScoreService;
import org.jin.samples.service.ISubjectService;
import org.jin.samples.service.ITestService;
import org.jin.samples.service.ITestTypeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller
public class ManageTestContreller {
	
	@Autowired
	private ITestService testService;
	
	@Autowired
	private ISubjectService subjectService;
	
	@Autowired
	private LocaleResolver localeResolver;
	
	@Autowired
	private ITestTypeService testTypeService;
	
	@Autowired
	private IScoreService scoreService;
	
	/*
	 * 国际化语言的切换操作
	 */
	@RequestMapping(value="/changeLocale")
	public String changeLocale(HttpServletRequest request, HttpServletResponse response, String localeType){
		if("en_US".equals(localeType)){
			localeResolver.setLocale(request, response, Locale.US);
		}else if("zh_CN".equals(localeType)){
			localeResolver.setLocale(request, response, Locale.CHINA);
		}
		return "redirect:/tests";
	}
	
	
	@RequestMapping(value="/tests")
	public String tofindAllTest(Model model){
		List<ExamTestType> testType = testTypeService.findAllTestType();
		List<ExamSubject> examSubject = subjectService.findAllSubject();
		PagerModel<ExamTest> pager =testService.findAllByPage(); //注意：类类型带泛型的的数据，在JSP调用时要细分出来，否则可能取不到你要的数据，包空指针异常
		model.addAttribute("SubjectList", examSubject);
		model.addAttribute("testType", testType);
		model.addAttribute("testList", pager);
		return "test/manageTest";
	}
	
	@ResponseBody
	@RequestMapping(value="/findByTestId", method = RequestMethod.POST)
	public ExamTestVO findByTestId(Integer testId){
		ExamTestVO Vo = testService.findByTest(testId);
		return Vo;
	}
	
	@ResponseBody
	@RequestMapping(value = "/saveTest", method = RequestMethod.POST)
	public CommonMessageResultVO addUser(@Valid ExamTestVO examTestVO, BindingResult bindingResult){
		CommonMessageResultVO resultVO = new CommonMessageResultVO();
		Map<String, String> messageMap = new HashMap<String, String>();
		resultVO.setSuccess(false);
		if(bindingResult.hasErrors()){
			List<ObjectError> errorList = bindingResult.getAllErrors();
			for(ObjectError error : errorList){
				FieldError fe = (FieldError) error;
				messageMap.put(fe.getField(), fe.getDefaultMessage());
			}
			resultVO.setMessageMap(messageMap);
			return resultVO;	
		}
		try {
			testService.addTest(examTestVO);
			resultVO.setSuccess(true);
		} catch (Exception e) {
			e.printStackTrace();
			messageMap.put("message", e.getMessage());
			resultVO.setMessageMap(messageMap);
		}
		return resultVO;
	}
	
	
	@ResponseBody
	@RequestMapping(value = "/editTest", method = RequestMethod.POST)
	public CommonMessageResultVO editUser(ExamTestVO examTestVO){
		CommonMessageResultVO resultVO = new CommonMessageResultVO();
		resultVO.setSuccess(false);
		try {
			testService.editTest(examTestVO);
			resultVO.setSuccess(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultVO;
	}
	
	
	@ResponseBody
	@RequestMapping(value = "/deleteUser", method = RequestMethod.POST)
	public CommonMessageResultVO deleteUser(Integer testId){
		CommonMessageResultVO resultVO = new CommonMessageResultVO();
		resultVO.setSuccess(false);
		try {
			testService.deleteUser(testId);
			resultVO.setSuccess(true);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return resultVO;	
	}
	
	@SuppressWarnings("unchecked")
	@RequestMapping(value="/joinTest")
	public String jointest(RedirectAttributes redirectAttributes, Model model, Integer hiddenSubId, Integer hiddenScoreId,HttpSession session)throws Exception{
	System.out.println("hiddenScoreId="+hiddenScoreId);	
	if(hiddenSubId != null && hiddenScoreId != null){
			session.setAttribute("ScoreId", hiddenScoreId);
			List<ExamTest> allTestList = testService.findAllBySubId(hiddenSubId); 
			ExamSubjectVO subject = subjectService.findSubjectById(hiddenSubId);
			if(allTestList.size()<subject.getTestCount()){//allTestList.size()查看数据库多少条题目信息
				redirectAttributes.addFlashAttribute("messageTest", "该科目的题数不足，不能考试");
				return "redirect:/score";
			}
			List<ExamTestVO> joinTest = null;
			long timelength = 0;
			
			if(session.getAttribute("joinTest")==null){
										//subject 试卷题数， 题目总分 ，test 数据库题目数， test对象
				joinTest = checkTestScore(subject.getTestCount(), subject.getTotalScore(), allTestList.size(), allTestList);
				if(joinTest == null){
					redirectAttributes.addFlashAttribute("messageTest","该试题的题数对应的分值不足，暂时不能考试");
					return "redirect:/score";	
				}
				session.setAttribute("joinTest", joinTest);
				Calendar calendar = Calendar.getInstance();  //创建日历对象
				calendar.setTime(new Date());  //初始化时间
				calendar.add(Calendar.MINUTE, subject.getTotalTime());  //现在的时间
				Date date  = calendar.getTime();
				session.setAttribute("time", date);
				timelength = (subject.getTotalTime()*60);  //总时间秒数
			}else{
				joinTest = (List<ExamTestVO>) session.getAttribute("joinTest");
				Date date = (Date) session.getAttribute("time");
				Date now = new Date();
				timelength = (date.getTime() - now.getTime())/1000;
			}	
			model.addAttribute("subject", subject);
			model.addAttribute("testList", new TestList());
			model.addAttribute("list", joinTest);
			int hour = (int) (timelength/3600);
			int minute = (int) (timelength/60-hour*60);
			int second = (int) (timelength-hour*3600-minute*60);
			model.addAttribute("dateTime_hour",hour);
			model.addAttribute("dateTime_minute",minute);
			model.addAttribute("dateTime_second",second);	
			return "test/joinTest";
	}else{
		return "redirect:/score";
	}
}
	
	@RequestMapping(value="/countScore")
	public String countScore(RedirectAttributes redirectAttributes,TestList testlist,HttpSession session)throws Exception{
		
		int score_q = 0;
		int scoreNum = 0;
		String quest = "";
		ExamUserVO userVO = new ExamUserVO();
		ExamScoreVO scoreVO = new ExamScoreVO();
		for(TestQuestion testQuestion : testlist.getQuestlist()){
			if(testQuestion != null){
				System.out.println(testQuestion.getHiddenId());
				System.out.println(testQuestion.getQ_1()+testQuestion.getQ_2()+testQuestion.getQ_3()+testQuestion.getQ_4()+testQuestion.getQ_5());
				if(testQuestion.getQ_1() != null){
					quest += testQuestion.getQ_1();
				}
				if(testQuestion.getQ_2() != null){
					quest += testQuestion.getQ_2();
				}
				if(testQuestion.getQ_3() != null){ 
					quest += testQuestion.getQ_3();
				}
				if(testQuestion.getQ_4() != null){
					quest += testQuestion.getQ_4();
				}
				score_q = countByTest(testQuestion.getHiddenId(),quest, testQuestion);	
			}else{
				score_q = 0;
			}
			scoreNum += score_q;
		}
		/*ScoreId*/
		Integer scoreId = (Integer) session.getAttribute("ScoreId");
		System.out.println("****scoreId*****"+scoreId);
		scoreVO.setId(scoreId);
		scoreVO.setExamTime(new Date());
		scoreVO.setScore((Integer)scoreNum);
		ExamSubject subject = subjectService.getSubjectById(testlist.getSubId());
		ExamUserVO examUserVO = (ExamUserVO) session.getAttribute("examUser");
		BeanUtils.copyProperties(examUserVO,userVO);
		scoreVO.setUserId(userVO);
		ExamSubjectVO subjectVO = new ExamSubjectVO();
		BeanUtils.copyProperties(subject,subjectVO);
		scoreVO.setSubjectId(subjectVO);
		scoreService.addScore(scoreVO);
		session.removeAttribute("joinTest");
		session.removeAttribute("time");
		return "redirect:/score";
	}
	
	//计算试题
	public Integer countByTest(Integer qId,String quest, TestQuestion testQuestion) throws Exception{
		Integer scoreNum = 0;
		ExamTestVO testVO = testService.findByTest(qId);
		String answer = testVO.getAnswer();
		String[] answerList = answer.split(",");
		for(String a : answerList){
			if(quest.indexOf(a) != -1){
				scoreNum = testVO.getExamTestTypeVo().getTestTypeScore();
			}else{
				scoreNum = 0;
				break;
			}
		}
		return scoreNum;
	}
	
	//获取随机试题
	public List<ExamTestVO> randomTest(List<ExamTest> allTestList, Integer Testcount){
		List<Integer> testIdList = new ArrayList<Integer>();
		List<Integer> allIdList = new ArrayList<Integer>();
		List<ExamTestVO> joinTest = new ArrayList<ExamTestVO>();
	    	Random random = new Random();
	    	for(ExamTest test : allTestList){
	    		allIdList.add(test.getId());
	    	}
	    	for(int i = 0 ; i < Testcount ; i ++){
	    		int maxindex = allIdList.size()-1; //index的最大值
	    		int randomIndex = random.nextInt(maxindex); //随机0到max
	    		int id = allIdList.get(randomIndex);	//获取随机的index里面的id值
	    		testIdList.add(id);		//把获取的id加入id链里
	    		try {
	    			joinTest.add(testService.findByTest(id)); //把对应id的test加入链里
				} catch (Exception e) {
					e.printStackTrace();
				}
	    		allIdList.remove(randomIndex); //移除查出来的testId 		
	    	}
		return joinTest;
	}
	
	
	//随机的试题是否满足总分						//subject 试卷题数， 题目总分 ，test 数据库题目数， test对象
	public List<ExamTestVO> checkTestScore(int count, double score, int length, List<ExamTest> allTestList){
		int a = length;
		int n = length-1;
		int d = count;
		int m = count-1;
		
		int e = length;
		int f = count-1;
		int nm = e-f-1;
		int nm1 = e-f;
		
		int testcount = length;
		int testcount1 = count;
		int testcount2 = nm1;
		
		for(int i = n ; i>0 ; i --){
			testcount = (testcount)*(--a);
		}
		for(int i = m ; i>0 ; i--){
			testcount1 = (testcount1)*(--d);
		}
		for(int i = nm ; i>0 ; i--){
			testcount2 = (testcount2)*(--nm1);
		}
		int Cnm = testcount/(testcount1*testcount2);//计算组合的格式
		List<ExamTestVO> joinTest = null;
		int num = 0;
		for(int i = Cnm; i>0 ; i--){
			double randomScore = 0.0;
			num++;
			
			joinTest = this.randomTest(allTestList, count);
			
			
			for(ExamTestVO vo : joinTest){//所有题目的分数总和
				randomScore += vo.getExamTestTypeVo().getTestTypeScore();
			}
			System.out.println(randomScore+"分");
			if(randomScore == score){
				return joinTest;
			}
		}
		System.out.println("随机查找了"+num+"次");
		return null;	
	}
	
}








